// ImageProcOpenCVLibTest.cpp : Defines the exported functions for the DLL application.
//

#include "stdafx.h"
#include "ImageProcOpenCVLib.h"
#include "IResize.h"
#include "UnitTestValidStep.h"
#include "ImageProcSteps.h"
#include "Windows.h"

class IResizeTest : public cfixcc::TestFixture
{
private:
	IResize* _pResize;
	ImageProcSteps *_steps;
	ImageProcStepLibs *_Libs;
	ImageExpt *_ief;

public:
	IResizeTest::IResizeTest()
	{
		_pResize = new IResize();
		_steps = new ImageProcSteps();
		_Libs = new ImageProcStepLibs();
		_ief = '\0';
	}

	IResizeTest::~IResizeTest()
	{
		if ( _Libs != '\0')
			delete _Libs;
		if (_pResize != '\0')
			delete _pResize;
		if (_steps != '\0')
			delete _steps;
		if (_ief != '\0')
			delete _ief;
	}

	bool LoadStdSteps()
	{
		bool rc = false;

		CFIXCC_ASSERT_EQUALS( true, _Libs->LoadLibs(L"C:\\Wills\\Bin\\"));
		CFIXCC_ASSERT_EQUALS( 2, _Libs->GetLibCount());		//ImageProcSampleLib.dll and ImageProcOpenCVLib.dll

		CFIXCC_ASSERT_EQUALS( true, ((_ief = ImageExpt::CreateImageExpt(L"C:\\Wills\\Test.ief", '\0', L"unit test", L"default", ImageExpt::FromDefaults)) != '\0'));
		CFIXCC_ASSERT_EQUALS( true, _ief->SaveFile());
		CFIXCC_ASSERT_EQUALS(true, ImageExptLib::IsFileExist(L"C:\\Wills\\Test.ief"));
		CFIXCC_ASSERT_EQUALS( true, (_ief->GetHeaderProcSteps() != '\0'));

		TiXmlElement *procStepsXml = _ief->GetHeaderProcSteps();
		procStepsXml->SetAttribute(ImageProcStepLibAuto::attribImageDllDir, "C:\\Wills\\Bin\\");  
		procStepsXml->Clear();	//remove default analysis step

		// 3. Setup the ImageProcSteps section of the IEF so it contains the Step you want to test

		// 3a. Set the library details for the FIRST step - "CalcAvContrast"

		TiXmlElement *procStepXml1 = TinyXmlLib::CreateSection (procStepsXml, ImageProcStep::xmlProcStep, "(give description)" );
		procStepXml1->SetAttribute("StepNum", 0);							//this is the first step
		procStepXml1->SetAttribute("LibName", "ImageProcOpenCVLib.dll");	//this is the library name - contains the function IResize::FunctionNameIResize ("ScaleResize")
		procStepXml1->SetAttribute("LibVer", "v1.0.0.1");					//this is the library version - should match setting in "ImageProcOpenCVLib.dll"
		procStepXml1->SetAttribute("IVer", 1);								//this is the library interface version - should match setting in "ImageProcOpenCVLib.dll"

		// 3b. Set the name of a function in the above library - see ImageProcSampleLib.xml created when you run ImageProcSampleApp.exe
		//		<Step LibName="ImageProcOpenCVLib.dll" LibVer="v1.0.0.0" IVer="1" Function="ScaleResize" >
		
		procStepXml1->SetAttribute("Function", IResize::FunctionNameIResize);				//name of the function that forms the step

		// 3c. Set the inputs for the above function name 

		TiXmlElement *InputsXml1 = TinyXmlLib::CreateSection (procStepXml1, ProcParamsInputs::xmlInputs, IResize::FunctionNameIResize );
		InputsXml1->SetAttribute("Count", 1);												//there is only 1 input param

		TiXmlElement *ip11 = TinyXmlLib::CreateSection (InputsXml1, ProcParam::XmlProcParam, "2.0" );
		ip11->SetAttribute("Name", "ScaleFactor");						
		ip11->SetAttribute("Index", 0);
		ip11->SetAttribute("Type", "DoubleP");

		// 3d. Set the outputs for the above function name 

		TiXmlElement *OutputsXml1 = TinyXmlLib::CreateSection (procStepXml1, ProcParamsOutputs::xmlOutputs, IResize::FunctionNameIResize );
		OutputsXml1->SetAttribute("Count", 1);

		TiXmlElement *op11 = TinyXmlLib::CreateSection (OutputsXml1, ProcParam::XmlProcParam, "0" );
		op11->SetAttribute("Name", ProcParam::attribOutputParamNameResult);		//ProcParam::attribOutputParamNameResult is "Result"
		op11->SetAttribute("Index", 0);											//Result must be Index 0
		op11->SetAttribute("Type", "IntP");										//Result is Double ("DoubleP") rather than Integer ("IntP") or String ("StringP")

		// 3e. Set the library details for the SECOND step -  "CalcScore" - the analysis step

		TiXmlElement *procStepXml2 = TinyXmlLib::CreateSection (procStepsXml, ImageProcStep::xmlProcStep, "(give description)" );
		procStepXml2->SetAttribute("StepNum", 1);						//this is the second step
		procStepXml2->SetAttribute("LibName", "ImageProcSample.dll");	//this is the library name - contains the function "CalcScore"
		procStepXml2->SetAttribute("LibVer", "v1.0.0.0");				//this is the library version - should match setting in "ImageProcSample.dll"
		procStepXml2->SetAttribute("IVer", 1);							//this is the library interface version - should match setting in "ImageProcSample.dll"

		// 3f. Set the name of a function in the above library - see ImageProcSampleLib.xml created when you run ImageProcSampleApp.exe
		//		<Step LibName="ImageProcSample.dll" LibVer="v1.0.0.0" IVer="1" Function="CalcScore" AnalysisStep="yes">
		
		procStepXml2->SetAttribute("Function", "CalcScore");				//name of the function that forms the step

		// 3c. Set the inputs for the above function name - see ImageProcSampleLib.xml created when you run ImageProcSampleApp.exe	
		//        <Inputs Count="1">CalcScore
		//            <Param Name="brightness" Index="0" Type="IntP">50</Param>
		//        </Inputs>

		TiXmlElement *InputsXml21 = TinyXmlLib::CreateSection (procStepXml2, ProcParamsInputs::xmlInputs, "CalcScore" );
		InputsXml21->SetAttribute("Count", 1);							//there is only 1 input param

		TiXmlElement *ip21 = TinyXmlLib::CreateSection (InputsXml21, ProcParam::XmlProcParam, "50" );
		ip21->SetAttribute("Name", "brightness");						//
		ip21->SetAttribute("Index", 0);
		ip21->SetAttribute("Type", "IntP");

		// 3d. Set the outputs for the above function name - see ImageProcSampleLib.xml created when you run ImageProcSampleApp.exe
		//        <Outputs Count="2">CalcScore
		//            <Param Name="Result" Index="0" Type="IntP">0</Param>
		//            <Param Name="Score" Index="1" Type="DoubleP">50.0</Param>
		//        </Outputs>
		//
		//  **** NOTE: Every step must have a "Result" output parameter and each collection of steps must contain a step with a "Score" output parameter (always a double) 
		//			   In this test we have two steps in the collection, so this second step must have both "Result" and "Score"

		TiXmlElement *OutputsXml2 = TinyXmlLib::CreateSection (procStepXml2, ProcParamsOutputs::xmlOutputs, "CalcScore" );
		OutputsXml2->SetAttribute("Count", 2);

		TiXmlElement *op21 = TinyXmlLib::CreateSection (OutputsXml2, ProcParam::XmlProcParam, "0" );
		op21->SetAttribute("Name", ProcParam::attribOutputParamNameResult);		//ProcParam::attribOutputParamNameResult is "Result"
		op21->SetAttribute("Index", 0);												//Result must be Index 0
		op21->SetAttribute("Type", "IntP");											//Result is Integer rather than Double ("DoubleP") or String ("StringP")

		TiXmlElement *op22 = TinyXmlLib::CreateSection (OutputsXml2, ProcParam::XmlProcParam, "0" );	//0.0 is the default value for result
		op22->SetAttribute("Name", ProcParam::attribOutputParamNameScore);		//ProcParam::attribOutputParamNameScore is "Score"
		op22->SetAttribute("Index", 1);												//Score must be Index 1
		op22->SetAttribute("Type", "DoubleP");										//Score is Double rather than Integer ("IntP") or String ("StringP")

		//Make a copy of file
		bool bFailIfExists = false;
		if (CopyFile(L"C:\\Wills\\originalimage.bmp", L"C:\\Wills\\image.bmp",  bFailIfExists) != 0)
		{
			rc = 1;
		}

		// 4. Initialise the collection of steps (_steps) from the ImageProcSteps section of the IEF 
		rc = _steps->LoadSteps(_ief, _Libs, L"c:\\wills\\image.bmp");
		
		if (rc == false)
			ClearStdSteps();

		return rc;	
	}
	
	void ClearStdSteps()
	{
		_steps->ClearAllSteps();
		_Libs->ClearAllLibs();		//returns true if GetLibCount() > 0
		_Libs->GetLibCount();

		if (_ief != '\0')
		{
			delete _ief;
			_ief = '\0';
		}
	}

	void Before()		//run before each of the following tests
	{
		

	}

	void After()		//run after each of the following tests
	{

	}

	void TestCreate()
	{
		CFIXCC_ASSERT_EQUALS(true, _pResize != '\0');
	}

	void TestProcessNullStep()
	{
		CFIXCC_ASSERT_EQUALS(false, _pResize->Process('\0', true));
	}

	void TestProcessInvalidStep()
	{
		ImageProcStep *step = new ImageProcStep();

		CFIXCC_ASSERT_EQUALS(false, _pResize->Process(step, true));
	}

	void TestProcessValidStep()
	{
		//*********************************************
		// setup 
		//*********************************************
		CFIXCC_ASSERT_EQUALS( true,  LoadStdSteps());

		CFIXCC_ASSERT_EQUALS( true,  _steps->IsValid());					
		CFIXCC_ASSERT_EQUALS( 2, _steps->GetStepCount());	//first step is "ScaleFactor" and second step is the analysis step "CalcScore" (ImageProcSample.dll) 

		ImageProcStep *stepResize = '\0';
		CFIXCC_ASSERT_EQUALS( true, (stepResize = _steps->GetStep(0)) != '\0');
		CFIXCC_ASSERT_EQUALS(IResize::FunctionNameIResize, stepResize->GetFunctionName());

		stepResize->SetIntermediateImagePathFilename("c:\\wills\\image.bmp");


		//*********************************************
		// test 
		//*********************************************

		CFIXCC_ASSERT_EQUALS(true, _pResize->Process(stepResize, true));		

		//*********************************************
		// clearup 
		//*********************************************
		ClearStdSteps();
	}

};

CFIXCC_BEGIN_CLASS( IResizeTest)
	CFIXCC_METHOD( TestCreate)
	CFIXCC_METHOD( TestProcessNullStep)
	CFIXCC_METHOD( TestProcessInvalidStep)
	CFIXCC_METHOD( TestProcessValidStep)
CFIXCC_END_CLASS()
